#!/usr/bin/env python
#
#       HandleArgs.py
#
#       Copyright 2008 karthikeyan S.<kaarthikeyapreyan@gmail.com>
#
#       This program is free software; you can redistribute it and/or modify
#       it under the terms of the GNU General Public License as published by
#       the Free Software Foundation; either version 2 of the License, or
#       (at your option) any later version.
#
#       This program is distributed in the hope that it will be useful,
#       but WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#       GNU General Public License for more details.
#
#       You should have received a copy of the GNU General Public License
#       along with this program; if not, write to the Free Software
#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#       MA 02110-1301, USA.

import os
import sys

import types

from inspect import getargspec

class Args:

    def describeArgs(self,attr):
        """
        Describe the arguments for every entity
        """
        try:
            arginfo = getargspec(attr)
        except TypeError,E:
            arginfo=[]

        return arginfo

    def formatargs(self,arginfo):
        """
        Gather the argument defaults
        and return a formatted list
        """
        defargvals = arginfo[3]
        if defargvals :
            defvallen = len(arginfo[3])
            basearglen = len(arginfo[0])
            defargs = arginfo[0][basearglen-defvallen:basearglen]
            argvals = zip(defargs, arginfo[3])
        else :
            argvals = []
        return argvals

def getargs(module,entitylist=[],retstate='print'):
    """
    usage:
        getargs(sample,entity=['testfunction','function']) or
        getargs(sample,entity=\
            [['testmethod','method','Testclass'],['testPrediction','class']])
    *Incase of method provide the class name as the third argument
    """
    module_imp=__import__(module)
    arginfo=[]

    if type(entitylist[0]) == types.ListType:
        for entity in entitylist:
            getargs(module,entity[1])
    else:
        if entitylist[1] == 'function':
            entity_attr=getattr(module_imp,entitylist[0])
            arginfo=Args().describeArgs(entity_attr)
        elif entitylist[1] == 'class':
            entity_attr=getattr(module_imp,entitylist[0])
            if '__init__' in dir(entity_attr):
                cl_attr=getattr(module_imp,entitylist[0])
                arginfo=Args().describeArgs(getattr(cl_attr,'__init__'))
        elif entitylist[1] == 'method':
            entity_attr=getattr(getattr(module_imp,entitylist[2]),entitylist[0])
            arginfo=Args().describeArgs(entity_attr)

        return _giveargs(arginfo,state=retstate)

def _giveargs(arginfo,state='raw'):

    arguments=None
    positional=None
    keywords=None
    defaults=[]

    if arginfo :
        if state == 'print':
            args = arginfo[0]
            pos_args = arginfo[1]
            kw_args=arginfo[2]
            if args :
                arguments="Arguments => %s"%(','.join(args))
            else :
                arguments="No Arguments specified"

            if not pos_args == None or pos_args == 'args':
                positional='Positional parameters => %s'%pos_args
            else :
                positional='Postional parameters => None'

            if not kw_args == None or kw_args == 'kwargs':
                keywords='Keyword parameters => %s'%kw_args
            else :
                keywords='kwargs => None'

            if Args().formatargs(arginfo):
                for (arg,val) in Args().formatargs(arginfo):
                    defaults.append('Default values for %s is %s'%(arg,val))
            else:
                defaults='Default Values => None'
        else :
            arguments = arginfo[0]
            positional = arginfo[1]
            keywords=arginfo[2]
            defaults=Args().formatargs(arginfo)

    return [arguments,positional,keywords,defaults]
